﻿#include "musicplaylist.h"
#include "ui_musicplaylist.h"

MusicPlaylist::MusicPlaylist(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MusicPlaylist)
{
    ui->setupUi(this);

    QString docLocation = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
    playListFile=docLocation + DEF_PLAYLIST;

    musicLocation=QStandardPaths::writableLocation(QStandardPaths::MusicLocation);
    playList=nullptr;

    model=new QStringListModel(this);
    ui->listView->setModel(model);

    QSettings cfg(M_CONFIG,QSettings::IniFormat);
    if(cfg.contains(M_KEY))
        player=new PlaylistPlayer(this,true);
    else
        player=new PlaylistPlayer(this);

    connect(player,SIGNAL(error(QMediaPlayer::Error)),this,SLOT(mediaError(QMediaPlayer::Error)));
    connect(player,SIGNAL(stateChanged(QMediaPlayer::State)),this,SLOT(stateChanged(QMediaPlayer::State)));

    createMenu();

    offline=player->isOfflineMode();
    if(offline)
    {
        connect(player,SIGNAL(currentMediaChanged(QMediaContent)),this,SLOT(currentMediaChanged(QMediaContent)));
        if(playList == nullptr)
            playList=new QMediaPlaylist(this);

        playList->setPlaybackMode(QMediaPlaylist::Sequential);
        loadDefaultFile();
    }
    else
    {
        connect(player,SIGNAL(currentName(QString)),this,SLOT(currentName(QString)));
        genDefaultList();
    }
}

MusicPlaylist::~MusicPlaylist()
{
    delete ui;
}

void MusicPlaylist::genDefaultList()
{
    QSqlQuery query(SELECT_COUNT);
    QSqlRecord record=query.record();
    if(record.count() == 0)
        return;
    while(query.next())
    {
        QString name=query.value(0).toString();
        QString path=query.value(1).toString();
        mediaFileList.append(name);
        playListItems.insert(name,path);
    }
    model->setStringList(mediaFileList);

    player->setNameList(mediaFileList);
    player->setPlaylistItems(playListItems);

    QString key=playListItems.value(mediaFileList.at(0));
    player->playMusic(QFileInfo(key));
}

void MusicPlaylist::loadDefaultFile()
{
    QFile file(playListFile);
    if(file.exists() && file.open(QFile::ReadOnly | QFile::Text))
    {
        playList->load(&file,"m3u");
        if(!playList->isEmpty())
        {
            player->setPlaylist(playList);
            player->play();

            for(int i=0;i<playList->mediaCount();i++)
            {
                QUrl url=playList->media(i).canonicalUrl();
                mediaFileList.append(url.toLocalFile());
            }
            model->setStringList(mediaFileList);
        }
    }
}
void MusicPlaylist::keyPressEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_Space:
        player->detectState();
        break;
    case Qt::Key_Escape:
        if(player->state() == QMediaPlayer::PlayingState ||
                player->state() == QMediaPlayer::PausedState )
            player->stop();
        else
            close();
        break;
    case Qt::Key_Up:
        playPrevious();
        break;
    case Qt::Key_Down:
        playNext();
        break;
    case Qt::Key_Left:
        playPrevious();
        break;
    case Qt::Key_Right:
        playNext();
        break;
    }
}

void MusicPlaylist::contextMenuEvent(QContextMenuEvent *)
{
    menu->exec(QCursor::pos());
}

void MusicPlaylist::createMenu()
{
    menu = new QMenu(this);
    if(offline)
    {
        addMediaAction=menu->addAction(QStringLiteral("添加"));
        connect(addMediaAction,&QAction::triggered,this,&MusicPlaylist::addMediaFile);

        removeMediaAction=menu->addAction(QStringLiteral("删除"));
        connect(removeMediaAction,&QAction::triggered,this,&MusicPlaylist::removeMediaFile);

        m_playMode=nullptr;
        playMode_TrackPlayOnce=nullptr;
        playMode_TrackPlayLoop=nullptr;
        playMode_ListPlaySequence=nullptr;
        playMode_ListPlayLoop=nullptr;
    }
    else
    {
        m_playMode=menu->addMenu(QStringLiteral("播放模式..."));

        playMode_TrackPlayOnce=m_playMode->addAction(QStringLiteral("单曲播放"));
        playMode_TrackPlayLoop=m_playMode->addAction(QStringLiteral("单曲循环"));
        playMode_ListPlaySequence=m_playMode->addAction(QStringLiteral("列表播放"));
        playMode_ListPlayLoop=m_playMode->addAction(QStringLiteral("列表循环"));

        connect(playMode_TrackPlayOnce,&QAction::triggered,this,&MusicPlaylist::setPlayMode_TrackPlayOnce);
        connect(playMode_TrackPlayLoop,&QAction::triggered,this,&MusicPlaylist::setPlayMode_TrackPlayLoop);
        connect(playMode_ListPlaySequence,&QAction::triggered,this,&MusicPlaylist::setPlayMode_ListPlaySequence);
        connect(playMode_ListPlayLoop,&QAction::triggered,this,&MusicPlaylist::setPlayMode_ListPlayLoop);

        addMediaAction=nullptr;
        removeMediaAction=nullptr;
    }
}

void MusicPlaylist::addMediaFile()
{
    QStringList fileList=QFileDialog::getOpenFileNames(this,QStringLiteral("选择音乐文件"),musicLocation,
                                                       QStringLiteral("音乐文件 (*.ogg *.mp3 *.wav)"));
    if(fileList.length() > 0)
    {
        mediaFileList.append(fileList);
        model->setStringList(mediaFileList);

        foreach (QString file, fileList) {
            playList->addMedia(QUrl(file));
        }

        QFile file(playListFile);
        if(file.open(QFile::WriteOnly | QFile::Text))
            playList->save(&file,"m3u");
    }
}

void MusicPlaylist::removeMediaFile()
{
    if(ui->listView->currentIndex().isValid())
    {
        int row=ui->listView->currentIndex().row();
        mediaFileList.removeAt(row);
        model->setStringList(mediaFileList);

        QFile file(playListFile);
        if(file.open(QFile::WriteOnly | QFile::Text))
            playList->save(&file,"m3u");
    }
}

void MusicPlaylist::mediaError(QMediaPlayer::Error error)
{
    switch (error) {
    case QMediaPlayer::FormatError:
        QMessageBox::warning(this,QStringLiteral("格式不支持"),QStringLiteral("当前平台未安装解码器，格式不支持"));
        break;
    default:
        QMessageBox::warning(this,QStringLiteral("异常错误"),QStringLiteral("发生异常错误，请联系开发者"));
        break;
    }
}

void MusicPlaylist::stateChanged(QMediaPlayer::State state)
{
    if(state == QMediaPlayer::StoppedState)
        ui->title->clear();
}

void MusicPlaylist::currentName(const QString &name)
{
    fileName=name;
    ui->title->setText(fileName);
}

void MusicPlaylist::on_listView_doubleClicked(const QModelIndex &index)
{
    if(index.isValid())
    {
        int row=index.row();
        if(offline)
            playList->setCurrentIndex(row);
        else
        {
            QString key=playListItems.value(mediaFileList.at(row));
            player->playMusic(QFileInfo(key));
        }
    }
}

void MusicPlaylist::currentMediaChanged(const QMediaContent &media)
{
    QUrl url=media.canonicalUrl();
    ui->title->setText(url.fileName());
}

void MusicPlaylist::setPlayMode_TrackPlayOnce()
{
    player->setPlayMode(PlaylistPlayer::TrackPlayOnce);
}

void MusicPlaylist::setPlayMode_TrackPlayLoop()
{
    player->setPlayMode(PlaylistPlayer::TrackPlayLoop);
}

void MusicPlaylist::setPlayMode_ListPlaySequence()
{
    player->setPlayMode(PlaylistPlayer::ListPlaySequence);
}

void MusicPlaylist::setPlayMode_ListPlayLoop()
{
    player->setPlayMode(PlaylistPlayer::ListPlayLoop);
}

void MusicPlaylist::playNext()
{
    if(offline)
        playList->next();
    else
    {
        if(mediaFileList.size() <= 1)
            return;

        int index=mediaFileList.indexOf(fileName);
        if(index == mediaFileList.size() -1)
            index=0;
        else
            index+=1;
        QString key=playListItems.value(mediaFileList.at(index));
        player->playMusic(QFileInfo(key));
    }
}

void MusicPlaylist::playPrevious()
{
    if(offline)
        playList->previous();
    else
    {
        if(mediaFileList.size() <= 1)
            return;

        int index=mediaFileList.indexOf(fileName);
        if(index == 0)
            index = mediaFileList.size() -1;
        else
            index-=1;
        QString key=playListItems.value(mediaFileList.at(index));
        player->playMusic(QFileInfo(key));
    }
}
